﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Entity;

using bdtheque.data.interfaces;
using bdtheque.data.poco;

namespace bdtheque.data.dataaccess
{
    // Implementation of the UnitOfWork Pattern
    public class UnitOfWork : IUnitOfWork
    {
        protected DbContext Context { get; set; } 

        // Application of the Liskov Substitution Principle (LSP) to store all generic Repositories in a dictionary
        private Dictionary<Type, Repository> repositoryDictionary = new Dictionary<Type, Repository>();

        public Dictionary<Type, Repository> RepositoryDictionary
        {
            get
            {
                return repositoryDictionary;
            }            
        }

        public UnitOfWork()
        {

        }

		public UnitOfWork(string connectionString)
		{
            if (connectionString == null)
                throw new ArgumentNullException("ConnectionString");

            Context = new DbContext(connectionString);
        }

        public Repository<T> GetRepository<T>()
            where T : class
        {
            return this.RepositoryDictionary[typeof(T)] as Repository<T>;            
        }

        public void AddRepository<T>(Repository<T> repository)
            where T : class
        {
            this.RepositoryDictionary.Add(typeof(T), repository);
        }

        public void Save()
        {
            int affectedRows = this.Context.SaveChanges();
        }

        public void Save(bool detectChanges)
        {
            if (detectChanges)
                this.Context.ChangeTracker.DetectChanges();

            Save();
        }

        public void Dispose()
        {
            if (this.Context != null)
                this.Context.Dispose();            

            GC.SuppressFinalize(this);
        }
    }
}
